/**
 * jQuery EasyUI 1.4
 *
 * Copyright (c) 2009-2014 www.jeasyui.com. All rights reserved.
 *
 * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt To use it
 * on other terms please contact us at info@jeasyui.com
 *
 */
(function ($) {
    function initialSetup(target) {
        var treegrid = $.data(target, "treegrid");
        var opts = treegrid.options;
        $(target).datagrid($.extend({}, opts, {
            url: null,
            data: null,
            loader: function () {
                return false;
            },
            onBeforeLoad: function () {
                return false;
            },
            onLoadSuccess: function () {
            },
            onResizeColumn: function (field, resize) {
                fixRowHeight(target);
                opts.onResizeColumn.call(target, field, resize);
            },
            onSortColumn: function (sortName, sortOrder) {
                opts.sortName = sortName;
                opts.sortOrder = sortOrder;
                if (opts.remoteSort) {
                    request(target);
                } else {
                    var data = $(target).treegrid("getData");
                    loadData(target, 0, data);
                }
                opts.onSortColumn.call(target, sortName, sortOrder);
            },
            onBeforeEdit: function (_a, _b) {
                if (opts.onBeforeEdit.call(target, _b) == false) {
                    return false;
                }
            },
            onAfterEdit: function (_c, _d, _e) {
                opts.onAfterEdit.call(target, _d, _e);
            },
            onCancelEdit: function (_f, row) {
                opts.onCancelEdit.call(target, row);
            },
            onSelect: function (id) {
                opts.onSelect.call(target, findNode(target, id));
            },
            onUnselect: function (id) {
                opts.onUnselect.call(target, findNode(target, id));
            },
            onCheck: function (id) {
                opts.onCheck.call(target, findNode(target, id));
            },
            onUncheck: function (id) {
                opts.onUncheck.call(target, findNode(target, id));
            },
            onClickRow: function (id) {
                opts.onClickRow.call(target, findNode(target, id));
            },
            onDblClickRow: function (id) {
                opts.onDblClickRow.call(target, findNode(target, id));
            },
            onClickCell: function (id, _17) {
                opts.onClickCell.call(target, _17, findNode(target, id));
            },
            onDblClickCell: function (id, _19) {
                opts.onDblClickCell.call(target, _19, findNode(target, id));
            },
            onRowContextMenu: function (e, id) {
                opts.onContextMenu.call(target, e, findNode(target, id));
            }
        }));
        if (!opts.columns) {
            var gridOpts = $.data(target, "datagrid").options;
            opts.columns = gridOpts.columns;
            opts.frozenColumns = gridOpts.frozenColumns;
        }
        treegrid.dc = $.data(target, "datagrid").dc;
        if (opts.pagination) {
            var pager = $(target).datagrid("getPager");
            pager.pagination({
                pageNumber: opts.pageNumber,
                pageSize: opts.pageSize,
                pageList: opts.pageList,
                buttons: opts.pageButtons,
                buttonPosition: opts.buttonPosition,
                showPageList: opts.showPageList,
                showPageStyle: opts.showPageStyle,
                showMsg: opts.showMsg,
                onSelectPage: function (pageNumber, pageSize) {
                    opts.pageNumber = pageNumber;
                    opts.pageSize = pageSize;
                    request(target);
                }
            });
            opts.pageSize = pager.pagination("options").pageSize;
        }
    };

    function fixRowHeight(target, id) {
        var gridOpts = $.data(target, "datagrid").options;
        var dc = $.data(target, "datagrid").dc;
        if (!dc.body1.is(":empty") && (!gridOpts.nowrap || gridOpts.autoRowHeight)) {
            if (id != undefined) {
                var childrens = getChildren(target, id);
                for (var i = 0; i < childrens.length; i++) {
                    _setFields(childrens[i][gridOpts.idField]);
                }
            }
        }
        $(target).datagrid("fixRowHeight", id);

        function _setFields(nodeId) {
            var tr1 = gridOpts.finder.getTr(target, nodeId, "body", 1);
            var tr2 = gridOpts.finder.getTr(target, nodeId, "body", 2);
            tr1.css("height", "");
            tr2.css("height", "");
            var maxHeight = Math.max(tr1.height(), tr2.height());
            tr1.css("height", maxHeight);
            tr2.css("height", maxHeight);
        };
    };

    function setRownumber(target) {
        var dc = $.data(target, "datagrid").dc;
        var opts = $.data(target, "treegrid").options;
        if (!opts.rownumbers) {
            return;
        }
        dc.body1.find("div.datagrid-cell-rownumber").each(function (i) {
            $(this).html(i + 1);
        });
    };

    function bindEvent(target) {
        var dc = $.data(target, "datagrid").dc;
        var bodys = dc.body1.add(dc.body2);
        var bodyHandler = ($.data(bodys[0], "events") || $._data(bodys[0], "events")).click[0].handler;
        dc.body1.add(dc.body2).bind("mouseover", function (e) {
            var tt = $(e.target);
            var tr = tt.closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            if (tt.hasClass("tree-hit")) {
                tt.hasClass("tree-expanded") ? tt.addClass("tree-expanded-hover") : tt.addClass("tree-collapsed-hover");
            }
            e.stopPropagation();
        }).bind("mouseout", function (e) {
            var tt = $(e.target);
            var tr = tt.closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            if (tt.hasClass("tree-hit")) {
                tt.hasClass("tree-expanded") ? tt.removeClass("tree-expanded-hover") : tt.removeClass("tree-collapsed-hover");
            }
            e.stopPropagation();
        }).unbind("click").bind("click", function (e) {
            var tt = $(e.target);
            var tr = tt.closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            if (tt.hasClass("tree-hit")) {
                toggleNode(target, tr.attr("node-id"));
            } else {
                bodyHandler(e);
            }
            e.stopPropagation();
        });
    };

    function appendTreeNode(target, id) {
        var opts = $.data(target, "treegrid").options;
        var tr1 = opts.finder.getTr(target, id, "body", 1);
        var tr2 = opts.finder.getTr(target, id, "body", 2);
        var fieldsLen1 = $(target).datagrid("getColumnFields", true).length + (opts.rownumbers ? 1 : 0);
        var fieldsLen2 = $(target).datagrid("getColumnFields", false).length;
        _insertTree(tr1, fieldsLen1);
        _insertTree(tr2, fieldsLen2);

        function _insertTree(tr, len) {
            $("<tr class=\"treegrid-tr-tree\">" + "<td style=\"border:0px\" colspan=\"" + len + "\">" + "<div></div>" + "</td>" + "</tr>").insertAfter(tr);
        };
    };

    function loadData(target, id, data, _bool) {
        var treegrid = $.data(target, "treegrid");
        var opts = treegrid.options;
        var dc = treegrid.dc;
        data = opts.loadFilter.call(target, data, id);
        var node = findNode(target, id);
        if (node) {
            var body1 = opts.finder.getTr(target, id, "body", 1);
            var body2 = opts.finder.getTr(target, id, "body", 2);
            var cc1 = body1.next("tr.treegrid-tr-tree").children("td").children("div");
            var cc2 = body2.next("tr.treegrid-tr-tree").children("td").children("div");
            if (!_bool) {
                node.children = [];
            }
        } else {
            var cc1 = dc.body1;
            var cc2 = dc.body2;
            if (!_bool) {
                treegrid.data = [];
            }
        }
        if (!_bool) {
            cc1.empty();
            cc2.empty();
        }
        if (opts.view.onBeforeRender) {
            opts.view.onBeforeRender.call(opts.view, target, id, data);
        }
        opts.view.render.call(opts.view, target, cc1, true);
        opts.view.render.call(opts.view, target, cc2, false);
        if (opts.showFooter) {
            opts.view.renderFooter.call(opts.view, target, dc.footer1, true);
            opts.view.renderFooter.call(opts.view, target, dc.footer2, false);
        }
        if (opts.view.onAfterRender) {
            opts.view.onAfterRender.call(opts.view, target);
        }
        if (!id && opts.pagination) {
            var total = $.data(target, "treegrid").total;
            var pager = $(target).datagrid("getPager");
            if (pager.pagination("options").total != total) {
                pager.pagination("refresh", {
                    total: total
                });
            }
        }
        fixRowHeight(target);
        setRownumber(target);
        showLines(target);
        $(target).treegrid("setSelectionState");
        $(target).treegrid("autoSizeColumn");
        opts.onLoadSuccess.call(target, node, data);
        $(target).datagrid("resize");
    };

    function request(target, id, queryParams, _bool, fnCall) {
        var opts = $.data(target, "treegrid").options;
        var bodys = $(target).datagrid("getPanel").find("div.datagrid-body");
        if (queryParams) {
            opts.queryParams = queryParams;
        }
        var optsQueryParams = opts.queryParams;
        if (typeof (opts.queryParams) == "function") {
            optsQueryParams = opts.queryParams();
        }
        var _queryParams = {};
        if (optsQueryParams) {
            if (typeof (optsQueryParams) == "object") {
                _queryParams = $.extend({}, optsQueryParams);
                _queryParams.queryString = $.parser.objConvertStr(optsQueryParams);
                if (opts.pagination) {
                    $.extend(_queryParams, {
                        page: opts.pageNumber,
                        rows: opts.pageSize
                    });
                }
                if (opts.sortName) {
                    $.extend(_queryParams, {
                        sort: opts.sortName,
                        order: opts.sortOrder
                    });
                }
            } else {
                //如果，使用字符串作为参数的话，就无法使用分页功能，那么分页功能必须作为字符串的形式传入
                _queryParams = optsQueryParams;
                if (opts.pagination) {
                    _queryParams = _queryParams + "&page=" + opts.pageNumber + "&rows=" + opts.pageSize;
                }
                if (opts.sortName) {
                    _queryParams = _queryParams + "&sort=" + opts.sortName + "&order=" + opts.sortOrder;
                }
            }
        } else {
            if (opts.pagination) {
                $.extend(_queryParams, {
                    page: opts.pageNumber,
                    rows: opts.pageSize
                });
            }
            if (opts.sortName) {
                $.extend(_queryParams, {
                    sort: opts.sortName,
                    order: opts.sortOrder
                });
            }
        }

        var row = findNode(target, id);
        if (opts.onBeforeLoad.call(target, row, _queryParams) == false) {
            return;
        }
        var folder = bodys.find("tr[node-id=\"" + id + "\"] span.tree-folder");
        folder.addClass("tree-loading");
        $(target).treegrid("loading");
        var _bb = opts.loader.call(target, _queryParams, function (data) {
            folder.removeClass("tree-loading");
            $(target).treegrid("loaded");
            loadData(target, id, data, _bool);
            if (fnCall) {
                fnCall();
            }
        }, function () {
            folder.removeClass("tree-loading");
            $(target).treegrid("loaded");
            opts.onLoadError.apply(target, arguments);
            if (fnCall) {
                fnCall();
            }
        });
        if (_bb == false) {
            folder.removeClass("tree-loading");
            $(target).treegrid("loaded");
        }
    };

    function getRoot(target) {
        var roots = getRoots(target);
        if (roots.length) {
            return roots[0];
        } else {
            return null;
        }
    };

    function getRoots(target) {
        return $.data(target, "treegrid").data;
    };

    function getParent(target, id) {
        var row = findNode(target, id);
        if (row._parentId) {
            return findNode(target, row._parentId);
        } else {
            return null;
        }
    };

    function getChildren(target, id) {
        var opts = $.data(target, "treegrid").options;
//		var _5c = $(target).datagrid("getPanel").find("div.datagrid-view2 div.datagrid-body");
        var nodeArray = [];
        if (id) {
            _findChildrenNode(id);
        } else {
            var roots = getRoots(target);
            for (var i = 0; i < roots.length; i++) {
                nodeArray.push(roots[i]);
                _findChildrenNode(roots[i][opts.idField]);
            }
        }

        function _findChildrenNode(nodeId) {
            var node = findNode(target, nodeId);
            if (node && node.children) {
                for (var i = 0, len = node.children.length; i < len; i++) {
                    var childrenNode = node.children[i];
                    nodeArray.push(childrenNode);
                    _findChildrenNode(childrenNode[opts.idField]);
                }
            }
        };
        return nodeArray;
    };

    function getLevel(target, id) {
        if (!id) {
            return 0;
        }
        var opts = $.data(target, "treegrid").options;
        var views = $(target).datagrid("getPanel").children("div.datagrid-view");
        var td = views.find("div.datagrid-body tr[node-id=\"" + id + "\"]").children("td[field=\"" + opts.treeField + "\"]");
        return td.find("span.tree-indent,span.tree-hit").length;
    };

    function findNode(target, id) {
        var opts = $.data(target, "treegrid").options;
        var data = $.data(target, "treegrid").data;
        var nodeArray = [data];
        while (nodeArray.length) {
            var c = nodeArray.shift();
            for (var i = 0; i < c.length; i++) {
                var node = c[i];
                if (node[opts.idField] == id) {
                    return node;
                } else {
                    if (node["children"]) {
                        nodeArray.push(node["children"]);
                    }
                }
            }
        }
        return null;
    };

    function collapseNode(target, id) {
        var opts = $.data(target, "treegrid").options;
        var row = findNode(target, id);
        var tr = opts.finder.getTr(target, id);
        var hit = tr.find("span.tree-hit");
        if (hit.length == 0) {
            return;
        }
        if (hit.hasClass("tree-collapsed")) {
            return;
        }
        if (opts.onBeforeCollapse.call(target, row) == false) {
            return;
        }
        // 是否只显示tree的一个图片
        if (opts.showfolder) {
            hit.removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
            hit.removeClass("tree-folder-open");
            hit.last().removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
        } else {
            hit.removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
            hit.next().removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
            hit.next().removeClass("tree-folder-open");
        }
        tr.removeClass("tr-tree-haschild");
        row.state = "closed";
        tr = tr.next("tr.treegrid-tr-tree");
        var cc = tr.children("td").children("div");
        if (opts.animate) {
            cc.slideUp("normal", function () {
                $(target).treegrid("autoSizeColumn");
                fixRowHeight(target, id);
                opts.onCollapse.call(target, row);
            });
        } else {
            cc.hide();
            $(target).treegrid("autoSizeColumn");
            fixRowHeight(target, id);
            opts.onCollapse.call(target, row);
        }
    }
    ;

    function expandNode(target, id) {
        var opts = $.data(target, "treegrid").options;
        var tr = opts.finder.getTr(target, id);
        var hit = tr.find("span.tree-hit");
        var row = findNode(target, id);
        if (hit.length == 0) {
            return;
        }
        if (hit.hasClass("tree-expanded")) {
            return;
        }
        if (opts.onBeforeExpand.call(target, row) == false) {
            return;
        }
        // 是否只显示tree的一个图片
        if (opts.showfolder) {
            hit.removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded tree-folder-open");
            hit.last().removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded");
        } else {
            hit.removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded");
            hit.next().removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded");
            hit.next().addClass("tree-folder-open");
        }
        tr.addClass("tr-tree-haschild");
        var nextTr = tr.next("tr.treegrid-tr-tree");
        if (nextTr.length) {
            var cc = nextTr.children("td").children("div");
            _openTreeNode(cc);
        } else {
            appendTreeNode(target, row[opts.idField]);
            var _nextTr = tr.next("tr.treegrid-tr-tree");
            var trDiv = _nextTr.children("td").children("div");
            trDiv.hide();
            var queryParams = $.extend({}, opts.queryParams || {});
            queryParams.id = row[opts.idField];
            request(target, row[opts.idField], queryParams, true, function () {
                if (trDiv.is(":empty")) {
                    _nextTr.remove();
                } else {
                    _openTreeNode(trDiv);
                }
            });
        }

        function _openTreeNode(cc) {
            row.state = "open";
            if (opts.animate) {
                cc.slideDown("normal", function () {
                    $(target).treegrid("autoSizeColumn");
                    fixRowHeight(target, id);
                    opts.onExpand.call(target, row);
                });
            } else {
                cc.show();
                $(target).treegrid("autoSizeColumn");
                fixRowHeight(target, id);
                opts.onExpand.call(target, row);
            }
        };
    };

    function toggleNode(target, id) {
        var opts = $.data(target, "treegrid").options;
        var tr = opts.finder.getTr(target, id);
        var hit = tr.find("span.tree-hit");
        if (hit.hasClass("tree-expanded")) {
            collapseNode(target, id);
        } else {
            expandNode(target, id);
        }
    };

    function collapseAll(target, node) {
        var opts = $.data(target, "treegrid").options;
        var childrens = getChildren(target, node);
        if (node) {
            childrens.unshift(findNode(target, node));
        }
        for (var i = 0; i < childrens.length; i++) {
            collapseNode(target, childrens[i][opts.idField]);
        }
    };

    function expandAll(target, node) {
        var opts = $.data(target, "treegrid").options;
        var childrens = getChildren(target, node);
        if (node) {
            childrens.unshift(findNode(target, node));
        }
        for (var i = 0; i < childrens.length; i++) {
            expandNode(target, childrens[i][opts.idField]);
        }
    }
    ;

    function expandTo(target, node) {
        var opts = $.data(target, "treegrid").options;
        var ids = [];
        var pNode = getParent(target, node);
        while (pNode) {
            var id = pNode[opts.idField];
            ids.unshift(id);
            pNode = getParent(target, id);
        }
        for (var i = 0; i < ids.length; i++) {
            expandNode(target, ids[i]);
        }
    };

    function appendNode(target, node) {
        var opts = $.data(target, "treegrid").options;
        if (node.parent) {
            var tr = opts.finder.getTr(target, node.parent);
            if (tr.next("tr.treegrid-tr-tree").length == 0) {
                appendTreeNode(target, node.parent);
            }
            var cell = tr.children("td[field=\"" + opts.treeField + "\"]").children("div.datagrid-cell");
            var icon = cell.children("span.tree-icon");
            if (icon.hasClass("tree-file")) {
                icon.removeClass("tree-file").addClass("tree-folder tree-folder-open");
                var hit = $("<span class=\"tree-hit tree-expanded\"></span>").insertBefore(icon);
                if (hit.prev().length) {
                    hit.prev().remove();
                }
            }
        }
        loadData(target, node.parent, node.data, true);
    };

    function insertNode(target, node) {
        var ref = node.before || node.after;
        var opts = $.data(target, "treegrid").options;
        var parent = getParent(target, ref);
        appendNode(target, {
            parent: (parent ? parent[opts.idField] : null),
            data: [node.data]
        });
        var rootNodes = parent ? parent.children : $(target).treegrid("getRoots");
        for (var i = 0; i < rootNodes.length; i++) {
            if (rootNodes[i][opts.idField] == ref) {
                var root = rootNodes[rootNodes.length - 1];
                rootNodes.splice(node.before ? i : (i + 1), 0, root);
                rootNodes.splice(rootNodes.length - 1, 1);
                break;
            }
        }
        _insertTrHtml(true);
        _insertTrHtml(false);
        setRownumber(target);
        showLines(target);

        function _insertTrHtml(viewType) {
            var type = viewType ? 1 : 2;
            var tr = opts.finder.getTr(target, node.data[opts.idField], "body", type);
            var btable = tr.closest("table.datagrid-btable");
            tr = tr.parent().children();
            var _tr = opts.finder.getTr(target, ref, "body", type);
            if (node.before) {
                tr.insertBefore(_tr);
            } else {
                var sub = _tr.next("tr.treegrid-tr-tree");
                tr.insertAfter(sub.length ? sub : _tr);
            }
            btable.remove();
        };
    };

    function removeNode(target, id) {
        var treegrid = $.data(target, "treegrid");
        $(target).datagrid("deleteRow", id);
        setRownumber(target);
        treegrid.total -= 1;
        $(target).datagrid("getPager").pagination("refresh", {
            total: treegrid.total
        });
        showLines(target);
    };

    function showLines(target) {
        var t = $(target);
        var opts = t.treegrid("options");
        if (opts.lines) {
            t.treegrid("getPanel").addClass("tree-lines");
        } else {
            t.treegrid("getPanel").removeClass("tree-lines");
            return;
        }
        t.treegrid("getPanel").find("span.tree-indent").removeClass("tree-line tree-join tree-joinbottom");
        t.treegrid("getPanel").find("div.datagrid-cell").removeClass("tree-node-last tree-root-first tree-root-one");
        var roots = t.treegrid("getRoots");
        if (roots.length > 1) {
            _getCellHtml(roots[0]).addClass("tree-root-first");
        } else {
            if (roots.length == 1) {
                _getCellHtml(roots[0]).addClass("tree-root-one");
            }
        }
        _addJoinBottom(roots);
        _addTreeLine(roots);

        function _addJoinBottom(_roots) {
            $.map(_roots, function (_node) {
                if (_node.children && _node.children.length) {
                    _addJoinBottom(_node.children);
                } else {
                    var cellHt = _getCellHtml(_node);
                    cellHt.find(".tree-icon").prev().addClass("tree-join");
                }
            });
            var celllestHt = _getCellHtml(_roots[_roots.length - 1]);
            celllestHt.addClass("tree-node-last");
            celllestHt.find(".tree-join").removeClass("tree-join").addClass("tree-joinbottom");
        };

        function _addTreeLine(_roots) {
            $.map(_roots, function (_node) {
                if (_node.children && _node.children.length) {
                    _addTreeLine(_node.children);
                }
            });
            for (var i = 0; i < _roots.length - 1; i++) {
                var _nd = _roots[i];
                var _level = t.treegrid("getLevel", _nd[opts.idField]);
                var tr = opts.finder.getTr(target, _nd[opts.idField]);
                var cc = tr.next().find("tr.datagrid-row td[field=\"" + opts.treeField + "\"] div.datagrid-cell");
                cc.find("span:eq(" + (_level - 1) + ")").addClass("tree-line");
            }
        };

        function _getCellHtml(_node) {
            var tr = opts.finder.getTr(target, _node[opts.idField]);
            var cellHt = tr.find("td[field=\"" + opts.treeField + "\"] div.datagrid-cell");
            return cellHt;
        };
    };
    $.fn.treegrid = function (options, param) {
        if (typeof options == "string") {
            var methods = $.fn.treegrid.methods[options];
            if (methods) {
                return methods(this, param);
            } else {
                return this.datagrid(options, param);
            }
        }
        options = options || {};
        return this.each(function () {
            var treegrid = $.data(this, "treegrid");
            if (treegrid) {
                $.extend(treegrid.options, options);
            } else {
                treegrid = $.data(this, "treegrid", {
                    options: $.extend({}, $.fn.treegrid.defaults, $.fn.treegrid.parseOptions(this), options),
                    data: []
                });
            }
            initialSetup(this);
            if (treegrid.options.data) {
                $(this).treegrid("loadData", treegrid.options.data);
            }
            if (treegrid.options.url) {
                request(this);
            }
            bindEvent(this);
        });
    };
    $.fn.treegrid.methods = {
        options: function (jq) {
            return $.data(jq[0], "treegrid").options;
        },
        resize: function (jq, param) {
            return jq.each(function () {
                $(this).datagrid("resize", param);
            });
        },
        fixRowHeight: function (jq, param) {
            return jq.each(function () {
                fixRowHeight(this, param);
            });
        },
        loadData: function (jq, node) {
            return jq.each(function () {
                loadData(this, node.parent, node);
            });
        },
        load: function (jq, param) {
            return jq.each(function () {
                $(this).treegrid("options").pageNumber = 1;
                $(this).treegrid("getPager").pagination({
                    pageNumber: 1
                });
                $(this).treegrid("reload", param);
            });
        },
        reload: function (jq, id) {
            return jq.each(function () {
                var opts = $(this).treegrid("options");
                var _queryParams = {};


                if (typeof id == "object") {
                    _queryParams = id;
                } else {
                    if (typeof (opts.queryParams) == "function") {
                        _queryParams = opts.queryParams();
                    } else {
                        _queryParams = $.extend({}, opts.queryParams);
                    }
                    _queryParams.id = id;
                }
                if (_queryParams.id) {
                    var node = $(this).treegrid("find", _queryParams.id);
                    if (node.children) {
                        node.children.splice(0, node.children.length);
                    }
                    opts.queryParams = _queryParams;
                    var tr = opts.finder.getTr(this, _queryParams.id);
                    tr.next("tr.treegrid-tr-tree").remove();
                    tr.find("span.tree-hit").removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
                    expandNode(this, _queryParams.id);
                } else {
                    request(this, null, _queryParams);
                }
            });
        },
        reloadFooter: function (jq, param) {
            return jq.each(function () {
                var opts = $.data(this, "treegrid").options;
                var dc = $.data(this, "datagrid").dc;
                if (param) {
                    $.data(this, "treegrid").footer = param;
                }
                if (opts.showFooter) {
                    opts.view.renderFooter.call(opts.view, this, dc.footer1, true);
                    opts.view.renderFooter.call(opts.view, this, dc.footer2, false);
                    if (opts.view.onAfterRender) {
                        opts.view.onAfterRender.call(opts.view, this);
                    }
                    $(this).treegrid("fixRowHeight");
                }
            });
        },
        getData: function (jq) {
            return $.data(jq[0], "treegrid").data;
        },
        getFooterRows: function (jq) {
            return $.data(jq[0], "treegrid").footer;
        },
        getRoot: function (jq) {
            return getRoot(jq[0]);
        },
        getRoots: function (jq) {
            return getRoots(jq[0]);
        },
        getParent: function (jq, id) {
            return getParent(jq[0], id);
        },
        getChildren: function (jq, id) {
            return getChildren(jq[0], id);
        },
        getLevel: function (jq, id) {
            return getLevel(jq[0], id);
        },
        find: function (jq, id) {
            return findNode(jq[0], id);
        },
        isLeaf: function (jq, id) {
            var opts = $.data(jq[0], "treegrid").options;
            var tr = opts.finder.getTr(jq[0], id);
            var hit = tr.find("span.tree-hit");
            return hit.length == 0;
        },
        select: function (jq, id) {
            return jq.each(function () {
                $(this).datagrid("selectRow", id);
            });
        },
        unselect: function (jq, id) {
            return jq.each(function () {
                $(this).datagrid("unselectRow", id);
            });
        },
        collapse: function (jq, id) {
            return jq.each(function () {
                collapseNode(this, id);
            });
        },
        expand: function (jq, id) {
            return jq.each(function () {
                expandNode(this, id);
            });
        },
        toggle: function (jq, id) {
            return jq.each(function () {
                toggleNode(this, id);
            });
        },
        collapseAll: function (jq, id) {
            return jq.each(function () {
                collapseAll(this, id);
            });
        },
        expandAll: function (jq, id) {
            return jq.each(function () {
                expandAll(this, id);
            });
        },
        expandTo: function (jq, id) {
            return jq.each(function () {
                expandTo(this, id);
            });
        },
        append: function (jq, param) {
            return jq.each(function () {
                appendNode(this, param);
            });
        },
        insert: function (jq, param) {
            return jq.each(function () {
                insertNode(this, param);
            });
        },
        remove: function (jq, id) {
            return jq.each(function () {
                removeNode(this, id);
            });
        },
        pop: function (jq, id) {
            var row = jq.treegrid("find", id);
            jq.treegrid("remove", id);
            return row;
        },
        refresh: function (jq, id) {
            return jq.each(function () {
                var opts = $.data(this, "treegrid").options;
                opts.view.refreshRow.call(opts.view, this, id);
            });
        },
        update: function (jq, param) {
            return jq.each(function () {
                var opts = $.data(this, "treegrid").options;
                opts.view.updateRow.call(opts.view, this, param.id, param.row);
            });
        },
        beginEdit: function (jq, id) {
            return jq.each(function () {
                $(this).datagrid("beginEdit", id);
                $(this).treegrid("fixRowHeight", id);
            });
        },
        endEdit: function (jq, id) {
            return jq.each(function () {
                $(this).datagrid("endEdit", id);
            });
        },
        cancelEdit: function (jq, id) {
            return jq.each(function () {
                $(this).datagrid("cancelEdit", id);
            });
        },
        showLines: function (jq) {
            return jq.each(function () {
                showLines(this);
            });
        }
    };
    $.fn.treegrid.parseOptions = function (target) {
        return $.extend({}, $.fn.datagrid.parseOptions(target), $.parser.parseOptions(target, ["treeField", {animate: "boolean"}]));
    };
    var viewTool = $.extend({}, $.fn.datagrid.defaults.view, {
        render: function (target, body, _bool) {
            var opts = $.data(target, "treegrid").options;
            var _field = $(target).datagrid("getColumnFields", _bool);
            var rowIdPrefix = $.data(target, "datagrid").rowIdPrefix;
            if (_bool) {
                if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) {
                    return;
                }
            }
            var viewToolthis = this;
            if (this.treeNodes && this.treeNodes.length) {
                var gridht = _gridHtml(_bool, this.treeLevel, this.treeNodes);
                $(body).append(gridht.join(""));
            }

            function _gridHtml(_bool, _treeLevel, _treeNodes) {
                var parent = $(target).treegrid("getParent", _treeNodes[0][opts.idField]);
                var leng = (parent ? parent.children.length : $(target).treegrid("getRoots").length) - _treeNodes.length;
                var btable = ["<table class=\"datagrid-btable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"];
                for (var i = 0; i < _treeNodes.length; i++) {
                    var row = _treeNodes[i];
                    if (row.state != "open" && row.state != "closed") {
                        row.state = "open";
                    }

                    var css = opts.rowStyler ? opts.rowStyler.call(target, row) : "";
                    var claName = "";
                    var styleName = "";
                    if (typeof css == "string") {
                        styleName = css;
                    } else {
                        if (css) {
                            claName = css["class"] || "";
                            styleName = css["style"] || "";
                        }
                    }
                    var cls = "";
                    if (row.state == "open") {
                        cls = "class=\"datagrid-row tr-tree-haschild " + (leng++ % 2 && opts.striped ? "datagrid-row-alt " : " ") + claName + "\"";
                    } else {
                        cls = "class=\"datagrid-row " + (leng++ % 2 && opts.striped ? "datagrid-row-alt " : " ") + claName + "\"";
                    }
                    var stName = styleName ? "style=\"" + styleName + "\"" : "";
                    var idName = rowIdPrefix + "-" + (_bool ? 1 : 2) + "-" + row[opts.idField];
                    btable.push("<tr id=\"" + idName + "\" node-id=\"" + row[opts.idField] + "\" " + cls + " " + stName + ">");
                    btable = btable.concat(viewToolthis.renderRow.call(viewToolthis, target, _field, _bool, _treeLevel, row));
                    btable.push("</tr>");
                    if (row.children && row.children.length) {
                        var tt = _gridHtml(_bool, _treeLevel + 1, row.children);
                        var v = row.state == "closed" ? "none" : "block";
                        //改变下选中样式
                        var childStyle = _treeLevel % 2 == 0 ? "treegrid-tr-tree-f" : "treegrid-tr-tree-t";
                        btable.push("<tr class=\"treegrid-tr-tree " + childStyle + "\"><td style=\"border:0px\" colspan=" + (_field.length + (opts.rownumbers ? 1 : 0)) + "><div style=\"display:" + v + "\">");
                        btable = btable.concat(tt);
                        btable.push("</div></td></tr>");
                    }
                }
                btable.push("</tbody></table>");
                return btable;
            };
        },
        renderFooter: function (target, footer, _bool) {
            var opts = $.data(target, "treegrid").options;
            var footers = $.data(target, "treegrid").footer || [];
            var _field = $(target).datagrid("getColumnFields", _bool);
            var ftable = ["<table class=\"datagrid-ftable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"];
            for (var i = 0; i < footers.length; i++) {
                var row = footers[i];
                row[opts.idField] = row[opts.idField] || ("foot-row-id" + i);
                ftable.push("<tr class=\"datagrid-row\" node-id=\"" + row[opts.idField] + "\">");
                ftable.push(this.renderRow.call(this, target, _field, _bool, 0, row));
                ftable.push("</tr>");
            }
            ftable.push("</tbody></table>");
            $(footer).html(ftable.join(""));
        },
        renderRow: function (target, _fields, _bool, id, row) {
            var opts = $.data(target, "treegrid").options;
            var cc = [];
            if (_bool && opts.rownumbers) {
                cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">0</div></td>");
            }
            for (var i = 0; i < _fields.length; i++) {
                var field = _fields[i];
                var col = $(target).datagrid("getColumnOption", field);
                if (col) {
                    var css = col.styler ? (col.styler(row[field], row) || "") : "";
                    var className = "";
                    var styleName = "";
                    if (typeof css == "string") {
                        styleName = css;
                    } else {
                        if (cc) {
                            className = css["class"] || "";
                            styleName = css["style"] || "";
                        }
                    }
                    var cls = className ? "class=\"" + className + "\"" : "";
                    var fieldName = col.hidden ? "style=\"display:none;" + styleName + "\"" : (styleName ? "style=\"" + styleName + "\"" : "");
                    cc.push("<td field=\"" + field + "\" " + cls + " " + fieldName + ">");
                    var fieldName = "";
                    if (!col.checkbox) {
                        if (col.align) {
                            fieldName += "text-align:" + col.align + ";";
                        }
                        if (!opts.nowrap) {
                            fieldName += "white-space:normal;height:auto;";
                        } else {
                            if (opts.autoRowHeight) {
                                fieldName += "height:auto;";
                            }
                        }
                    }
                    cc.push("<div style=\"" + fieldName + "\" ");
                    if (col.checkbox) {
                        cc.push("class=\"datagrid-cell-check ");
                    } else {
                        cc.push("class=\"datagrid-cell " + col.cellClass);
                    }
                    cc.push("\">");
                    if (col.checkbox) {
                        if (row.checked) {
                            cc.push("<input type=\"checkbox\" checked=\"checked\"");
                        } else {
                            cc.push("<input type=\"checkbox\"");
                        }
                        cc.push(" name=\"" + field + "\" value=\"" + (row[field] != undefined ? row[field] : "") + "\">");
                    } else {
                        var val = null;
                        if (col.formatter) {
                            val = col.formatter(row[field], row, field);
                        } else {
                            var value = row[field];
                            var dictionString = null;
                            try {
                                dictionString = dictionaryJson;
                            } catch (e) {
                            }
                            ;
                            if (col.dictionary && dictionString) {
                                try {
                                    value = dictionaryJson[col.dictionary][value];
                                } catch (e) {
                                }
                                ;
                            }
                            if (col.dateFormatt && value) {
                                try {
                                    var data = $.parser.parseDate(col.dateFormatt, value);
                                    value = $.parser.formatDate(col.dateFormatt, data);
                                } catch (e) {
                                }
                                ;
                            }
                            val = value || "";
                        }
                        if (field == opts.treeField) {
                            for (var j = 0; j < id; j++) {
                                cc.push("<span class=\"tree-indent\"></span>");
                            }
                            if (row.state == "closed") {
                                cc.push("<span class=\"tree-hit tree-collapsed\"></span>");
                                //cc.push("<span class=\"tree-icon tree-folder " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                if (opts.showfolder) {
                                    cc.push("<span class=\"tree-hit tree-icon tree-folder tree-collapsed " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                } else {
                                    cc.push("<span class=\"tree-icon tree-folder tree-collapsed " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                }
                            } else {
                                if (row.children && row.children.length) {
                                    cc.push("<span class=\"tree-hit tree-expanded\"></span>");
                                    //cc.push("<span class=\"tree-icon tree-folder tree-folder-open " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                    if (opts.showfolder) {
                                        cc.push("<span class=\"tree-hit tree-icon tree-folder tree-folder-open tree-expanded " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                    } else {
                                        cc.push("<span class=\"tree-icon tree-folder tree-folder-open tree-expanded " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                    }
                                } else {
                                    cc.push("<span class=\"tree-indent\"></span>");
                                    cc.push("<span class=\"tree-icon tree-file " + (row.iconCls ? row.iconCls : "") + "\"></span>");
                                }
                            }
                            cc.push("<span class=\"tree-title\">" + val + "</span>");
                        } else {
                            cc.push(val);
                        }
                    }
                    cc.push("</div>");
                    cc.push("</td>");
                }
            }
            return cc.join("");
        },
        refreshRow: function (_e9, id) {
            this.updateRow.call(this, _e9, id, {});
        },
        updateRow: function (target, id, row) {
            var opts = $.data(target, "treegrid").options;
            var node = $(target).treegrid("find", id);
            $.extend(node, row);
            var level = $(target).treegrid("getLevel", id) - 1;
            var rowStyler = opts.rowStyler ? opts.rowStyler.call(target, node) : "";
            var rowIdPrefix = $.data(target, "datagrid").rowIdPrefix;
            var nodeId = node[opts.idField];

            function _checkedBoxSelected(viewType) {
                var columnFields = $(target).treegrid("getColumnFields", viewType);
                var tr = opts.finder.getTr(target, id, "body", (viewType ? 1 : 2));
                var rowHtml = tr.find("div.datagrid-cell-rownumber").html();
                var checked = tr.find("div.datagrid-cell-check input[type=checkbox]").is(":checked");
                tr.html(this.renderRow(target, columnFields, viewType, level, node));
                if (row.state == "open") {
                    tr.addClass("tr-tree-haschild");
                }
                tr.attr("style", rowStyler || "");
                tr.find("div.datagrid-cell-rownumber").html(rowHtml);
                if (checked) {
                    tr.find("div.datagrid-cell-check input[type=checkbox]")._propAttr("checked", true);
                }
                if (nodeId != id) {
                    tr.attr("id", rowIdPrefix + "-" + (viewType ? 1 : 2) + "-" + nodeId);
                    tr.attr("node-id", nodeId);
                }
            };
            _checkedBoxSelected.call(this, true);
            _checkedBoxSelected.call(this, false);
            $(target).treegrid("fixRowHeight", id);
        },
        deleteRow: function (target, id) {
            var opts = $.data(target, "treegrid").options;
            var tr = opts.finder.getTr(target, id);
            tr.next("tr.treegrid-tr-tree").remove();
            tr.remove();
            var node = del(id);
            if (node) {
                if (node.children.length == 0) {
                    tr = opts.finder.getTr(target, node[opts.idField]);
                    tr.next("tr.treegrid-tr-tree").remove();
                    var cell = tr.children("td[field=\"" + opts.treeField + "\"]").children("div.datagrid-cell");
                    cell.find(".tree-icon").removeClass("tree-folder").addClass("tree-file");
                    cell.find(".tree-hit").remove();
                    $("<span class=\"tree-indent\"></span>").prependTo(cell);
                }
            }

            function del(id) {
                var cc;
                var parent = $(target).treegrid("getParent", id);
                if (parent) {
                    cc = parent.children;
                } else {
                    cc = $(target).treegrid("getData");
                }
                for (var i = 0; i < cc.length; i++) {
                    if (cc[i][opts.idField] == id) {
                        cc.splice(i, 1);
                        break;
                    }
                }
                return parent;
            };
        },
        onBeforeRender: function (target, id, pageObject) {
            if ($.isArray(id)) {
                pageObject = {
                    total: id.length,
                    rows: id
                };
                id = null;
            }
            if (!pageObject) {
                return false;
            }
            var treegrid = $.data(target, "treegrid");
            var opts = treegrid.options;
            if (pageObject.length == undefined) {
                if (pageObject.footer) {
                    treegrid.footer = pageObject.footer;
                }
                if (pageObject.total) {
                    treegrid.total = pageObject.total;
                }
                pageObject = this.transfer(target, id, pageObject.rows);
            } else {
                function _setRowParentId(_pageObject, _id) {
                    for (var i = 0; i < _pageObject.length; i++) {
                        var row = _pageObject[i];
                        row._parentId = _id;
                        if (row.children && row.children.length) {
                            _setRowParentId(row.children, row[opts.idField]);
                        }
                    }
                };
                _setRowParentId(pageObject, id);
            }
            var node = findNode(target, id);
            if (node) {
                if (node.children) {
                    node.children = node.children.concat(pageObject);
                } else {
                    node.children = pageObject;
                }
            } else {
                treegrid.data = treegrid.data.concat(pageObject);
            }
            this.sort(target, pageObject);
            this.treeNodes = pageObject;
            this.treeLevel = $(target).treegrid("getLevel", id);
        },
        sort: function (target, pageObject) {
            var opts = $.data(target, "treegrid").options;
            if (!opts.remoteSort && opts.sortName) {
                var sortNameArray = opts.sortName.split(",");
                var sortOrderArray = opts.sortOrder.split(",");
                _106(pageObject);
            }

            function _106(_pageObject) {
                _pageObject.sort(function (r1, r2) {
                    var r = 0;
                    for (var i = 0; i < sortNameArray.length; i++) {
                        var sn = sortNameArray[i];
                        var so = sortOrderArray[i];
                        var col = $(target).treegrid("getColumnOption", sn);
                        var _107 = col.sorter || function (a, b) {
                            return a == b ? 0 : (a > b ? 1 : -1);
                        };
                        r = _107(r1[sn], r2[sn]) * (so == "asc" ? 1 : -1);
                        if (r != 0) {
                            return r;
                        }
                    }
                    return r;
                });
                for (var i = 0; i < _pageObject.length; i++) {
                    var children = _pageObject[i].children;
                    if (children && children.length) {
                        _106(children);
                    }
                }
            };
        },
        transfer: function (target, _10a, data) {
            var opts = $.data(target, "treegrid").options;
            var rows = [];
            for (var i = 0; i < data.length; i++) {
                rows.push(data[i]);
            }
            var _10b = [];
            for (var i = 0; i < rows.length; i++) {
                var row = rows[i];
                if (!_10a) {
                    if (!row._parentId) {
                        _10b.push(row);
                        rows.splice(i, 1);
                        i--;
                    }
                } else {
                    if (row._parentId == _10a) {
                        _10b.push(row);
                        rows.splice(i, 1);
                        i--;
                    }
                }
            }
            var toDo = [];
            for (var i = 0; i < _10b.length; i++) {
                toDo.push(_10b[i]);
            }
            while (toDo.length) {
                var node = toDo.shift();
                for (var i = 0; i < rows.length; i++) {
                    var row = rows[i];
                    if (row._parentId == node[opts.idField]) {
                        if (node.children) {
                            node.children.push(row);
                        } else {
                            node.children = [row];
                        }
                        toDo.push(row);
                        rows.splice(i, 1);
                        i--;
                    }
                }
            }
            return _10b;
        }
    });
    $.fn.treegrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
        treeField: null,
        lines: false,
        animate: false,
        singleSelect: true,
        showfolder: false,
        view: viewTool,
        loader: function (param, successCall, errorCall) {
            var opts = $(this).treegrid("options");
            if (!opts.url) {
                return false;
            }
            $.ajax({
                type: opts.method,
                url: opts.url,
                data: param,
                dataType: "json",
                success: function (data) {
                    if (jQuery.isArray(data)) {
                        successCall(data);
                    } else if (data.status) {
                        successCall(data.content);
                    } else {
                        $.messager.show({
                            title: "消息提示",
                            msg: data.message || "加载数据异常",
                            showType: "slide",
                            style: {
                                right: '',
                                top: document.body.scrollTop + document.documentElement.scrollTop,
                                bottom: ''
                            }
                        }, "error");
                        errorCall.apply(this, arguments);
                    }
                },
                error: function () {
                    errorCall.apply(this, arguments);
                }
            });
        },
        loadFilter: function (data, _10f) {
            return data;
        },
        finder: {
            getTr: function (target, id, type, body) {
                type = type || "body";
                body = body || 0;
                var dc = $.data(target, "datagrid").dc;
                if (body == 0) {
                    var opts = $.data(target, "treegrid").options;
                    var tr1 = opts.finder.getTr(target, id, type, 1);
                    var tr2 = opts.finder.getTr(target, id, type, 2);
                    return tr1.add(tr2);
                } else {
                    if (type == "body") {
                        var tr = $("#" + $.data(target, "datagrid").rowIdPrefix + "-" + body + "-" + id);
                        if (!tr.length) {
                            tr = (body == 1 ? dc.body1 : dc.body2).find("tr[node-id=\"" + id + "\"]");
                        }
                        return tr;
                    } else {
                        if (type == "footer") {
                            return (body == 1 ? dc.footer1 : dc.footer2).find("tr[node-id=\"" + id + "\"]");
                        } else {
                            if (type == "selected") {
                                return (body == 1 ? dc.body1 : dc.body2).find("tr.datagrid-row-selected");
                            } else {
                                if (type == "highlight") {
                                    return (body == 1 ? dc.body1 : dc.body2).find("tr.datagrid-row-over");
                                } else {
                                    if (type == "checked") {
                                        return (body == 1 ? dc.body1 : dc.body2).find("tr.datagrid-row-checked");
                                    } else {
                                        if (type == "last") {
                                            return (body == 1 ? dc.body1 : dc.body2).find("tr:last[node-id]");
                                        } else {
                                            if (type == "allbody") {
                                                return (body == 1 ? dc.body1 : dc.body2).find("tr[node-id]");
                                            } else {
                                                if (type == "allfooter") {
                                                    return (body == 1 ? dc.footer1 : dc.footer2).find("tr[node-id]");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            getRow: function (target, p) {
                var id = (typeof p == "object") ? p.attr("node-id") : p;
                return $(target).treegrid("find", id);
            },
            getRows: function (target) {
                return $(target).treegrid("getChildren");
            }
        },
        onBeforeLoad: function (row, _114) {
        },
        onLoadSuccess: function (row, data) {
        },
        onLoadError: function () {
        },
        onBeforeCollapse: function (row) {
        },
        onCollapse: function (row) {
        },
        onBeforeExpand: function (row) {
        },
        onExpand: function (row) {
        },
        onClickRow: function (row) {
        },
        onDblClickRow: function (row) {
        },
        onClickCell: function (_115, row) {
        },
        onDblClickCell: function (_116, row) {
        },
        onContextMenu: function (e, row) {
        },
        onBeforeEdit: function (row) {
        },
        onAfterEdit: function (row, _117) {
        },
        onCancelEdit: function (row) {
        }
    });
})(jQuery);
